package com.chinaums.open.api;

import com.chinaums.open.api.constants.ConfigBean;
import com.chinaums.open.api.internal.util.OpenApiLogger;
import com.chinaums.open.api.internal.util.http.HttpTransport;
import com.chinaums.open.api.parser.json.ObjectJsonParser;
import org.apache.commons.lang3.StringUtils;

import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * User: ZHANGWEI
 * Date: 2016/12/2
 * Time: 14:22
 * 所属模块：
 * 功能说明：开放平台客户端
 */
public class DefaultOpenApiClient implements OpenApiClient {
    private static final String constant_classname= DefaultOpenApiClient.class.getSimpleName();
    /**
     * 开放平台URL
     */
    private String serverUrl;
    /**
     * appId
     */
    private String appId;
    /**
     * appKey
     */
    private String appKey;
    /**
     * 字符集格式
     */
    private String encodeCharSet;

    public DefaultOpenApiClient(String serverUrl, String appId, String appKey) {
        this.serverUrl = serverUrl;
        this.appId = appId;
        this.appKey = appKey;
    }

    public DefaultOpenApiClient(String serverUrl, String appId, String appKey, String encodeCharSet) {
        this.serverUrl = serverUrl;
        this.appId = appId;
        this.appKey = appKey;
        this.encodeCharSet = encodeCharSet;
    }

    public <T extends OpenApiResponse> T execute(OpenApiRequest<T> openApiRequest) throws OpenApiException {
        return execute(openApiRequest,null,null);
    }

    public <T extends OpenApiResponse> T execute(OpenApiRequest<T> openApiRequest, String token) throws OpenApiException {
        return execute(openApiRequest,token,null);
    }

    public <T extends OpenApiResponse> T execute(OpenApiRequest<T> openApiRequest, String token, String encodeCharSet) throws OpenApiException {
        OpenApiParser<T> openApiParser = new ObjectJsonParser<T>(openApiRequest.responseClass());
        return execute_(openApiRequest,openApiParser,token,encodeCharSet);
    }

    public <T extends OpenApiResponse> T execute_(OpenApiRequest<T> openApiRequest, OpenApiParser<T> openApiParser, String token, String encodeCharSet){
        ConfigBean configBean = new ConfigBean();
        OpenApiContext context = new OpenApiContext();
        T trsp = null;
        String response = "";
        try {
            if(StringUtils.isBlank(serverUrl)) throw new OpenApiException("通讯地址未设置");
            if(StringUtils.isBlank(appId)) throw new OpenApiException("开发者appId未设置");
            if(StringUtils.isBlank(appKey)) throw new OpenApiException("开发者appKey未设置");
            String request = openApiParser.validRequest(openApiRequest);
            context.setStartTime(System.currentTimeMillis());
            context.setRequestId(UUID.randomUUID().toString().replace("-",""));
            context.setOpenServUrl(serverUrl);
            String url = serverUrl.concat(openApiRequest.apiVersion()).concat(openApiRequest.serviceCode());
            context.setApiServiceUrl(url);
            context.setApiMethodName(openApiRequest.apiMethodName());
            context.setVersion(openApiRequest.apiVersion());
            context.setAppId(appId);
            context.setAppKey(appKey);
            context.setConfigBean(configBean);
            context.setServiceCode(openApiRequest.serviceCode());
            if(openApiRequest.needToken()){
                OpenApiCache.getCurrentToken(context);
                response = HttpTransport.getInstance().doPost(context,request);
            }else{
                response = HttpTransport.getInstance().doPost(configBean.isProd(),url,token,request);
            }
            if(StringUtils.isBlank(response)) throw new OpenApiException("服务提供方未返回");
            if(StringUtils.isNotBlank(encodeCharSet)){
                //encodeCharSet = configBean.getCharSet();
                trsp = openApiParser.parse(new String(response.getBytes(),encodeCharSet));
            }else{
                trsp = openApiParser.parse(response);
            }
        } catch (Exception e) {
            OpenApiLogger.logError(constant_classname +" SDK异常:"+e.getStackTrace());
            e.printStackTrace();
        }
        context.setEndTime(System.currentTimeMillis());
        return trsp;
    }
}
